/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Description: Hmfs-tools resize operator
 */

#ifndef RESIZE_OPERATOR_H
#define RESIZE_OPERATOR_H

#include <iostream>

#include "hmfs_fs.h"
#include "hmfs_log.h"
#include "resize_command.h"
#include "resize_data.h"
#include "resize_defrag.h"
#include "resize_load.h"
#include "resize_utils.h"

namespace OHOS {
namespace Hmfs {
class ResizeDefrag;
class ResizeOperator {
public:
    ResizeOperator(CmdConfig &resizeConfig);
    ~ResizeOperator();
    void InitConfig();
    int32_t GetNewSuperBlock(SuperBlockData *superBlockData);
    int32_t ShrinkNats(SuperBlockData *newSuperBlockData);
    int32_t GetSumEntry(uint32_t blkAddr, SummaryEntry *sumEntry);
    SummaryBlockData *GetSumBlock(uint32_t sitNumber, int32_t *retType);
    int32_t MigrateMainArea(uint32_t offset);
    void MoveSsa(uint32_t sitNumber, uint32_t newSumBlkAddr);
    void UpdateDataBlkaddr(uint32_t nodeId, uint16_t nodeBlockOffset, uint32_t newAddr);
    void UpdateNatBlkaddr(uint32_t inodeNumber, uint32_t nodeId, uint32_t newaddr);
    int32_t MigrateSsa(SuperBlockData *newSuperBlockData, uint32_t offset);
    int32_t MigrateNat(SuperBlockData *newSuperBlockData);
    int32_t MigrateSit(SuperBlockData *newSuperBlockData, uint32_t offset);
    void RebuildCheckpoint(SuperBlockData *newSuperBlockData, uint32_t offset);
    int32_t HmfsResizeCheck(SuperBlockData *newSuperBlockData);
    int32_t FlushNatJournalEntries();
    void RewriteCurrentSitPage(uint32_t sitNumber, SitBlockData *sitBlk);
    int32_t FlushSitJournalEntries();
    void DuplicateCheckpoint();
    uint32_t UpdateNatBitsFlags(SuperBlockData *superBlockData, CheckPointData *checkPointData, uint32_t flags);
    void WriteNatBits(SuperBlockData *superBlockData, CheckPointData *checkPointData, int32_t set);
    void WriteCheckpoint();
    void DupWriteCheckpoints();
    void FlushJournalEntries();
    int32_t HmfsResizeExpand();
    int32_t HmfsResizeShrink();
    int32_t HmfsResize();
    int32_t CreateDeviceInfo();
    int32_t InitDeviceInfoToConfig();

private:
    void UpdateCheckpointSegments(SuperBlockData *superBlockData,
        CheckPointData *checkPointData, SuperBlockData *newSuperBlockData, uint32_t offset, uint32_t orphanBlocks);
    void UpdateCurrentSegments(CheckPointData *checkPointData, uint32_t offset);
    void UpdateVersionBitmapSizes(CheckPointData *checkPointData, SuperBlockData *newSuperBlockData);
    void UpdateCheckpointFlags(CheckPointData *checkPointData, SuperBlockData *newSuperBlockData, uint32_t &flags);
    void WriteNewCheckpoint(SuperBlockData *superBlockData, CheckPointData *checkPointData,
        SuperBlockData *newSuperBlockData, uint32_t orphanBlocks, uint32_t flags);
    void HandleOrphanBlocksAndWriteSegments(uint8_t *buf, uint32_t oldCheckPointBlockId,
        uint32_t &newCheckPointBlockId, uint32_t orphanBlocks, SuperBlockData *newSuperBlockData);
    void SetCheckPointFlags(CheckPointData *checkPointData, uint32_t &flags, uint32_t &orphanBlocks);
    void UpdateCheckPointData(CheckPointData *checkPointData, SuperBlockData *superBlockData,
        uint32_t orphanBlocks);
    void WriteCheckPointData(CheckPointData *checkPointData, SuperBlockData *superBlockData,
        uint32_t orphanBlocks, uint32_t flags);
    void WriteCurrentSegments(unsigned long long &checkPointBlockNumber, SuperBlockData *superBlockData);
    void HandleUnsafeResize(SuperBlockData *superBlockData, uint32_t blockPerSeg, uint32_t segsPerZone);
    void CalculateMainBlockId(SuperBlockData *superBlockData, uint32_t blockPerSeg, uint32_t segsPerZone);
    void CalculateSsaBlockId(SuperBlockData *superBlockData, uint32_t blockPerSeg);
    void CalculateSitBitmapSize(SuperBlockData *superBlockData, uint32_t blockPerSeg, uint32_t segsPerZone,
        uint32_t &maxNatBitmapSize);
    void CalculateNatSegments(SuperBlockData *superBlockData, uint32_t blockPerSeg, uint32_t &maxNatBitmapSize);
    void CalculateSitSegments(SuperBlockData *superBlockData, uint32_t blockPerSeg);
    int32_t PerformResize();
    void PrepareNatBits(SuperBlockData *superBlockData, CheckPointData *checkPointData, uint8_t *natBits,
        uint8_t *fullNatBits, uint8_t *emptyNatBits);
    CmdConfig &resizeConfig_;
    std::shared_ptr<HmfsConfigData> config_ = nullptr;
    std::shared_ptr<HmfsSuperBlockInfo> superBlockInfo_ = nullptr;
    std::unique_ptr<ResizeDefrag> resizeDefrag_ = nullptr;
};

} // namespace Hmfs
} // namespace OHOS
#endif // RESIZE_OPERATOR_H
